package per.jdz.pc.sync;

public class A {
    public static void main(String[] args) {
        Data data = new Data(0);
        new Thread(()-> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "A").start();
        new Thread(()-> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "B").start();
        new Thread(()-> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.increment();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "C").start();
        new Thread(()-> {
            for (int i = 0; i < 10; i++) {
                try {
                    data.decrement();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, "D").start();
        System.out.println("main end");
    }
}

// 资源类
// 等待 业务 通知
class Data {
    private int num;

    public Data(int num) {
        this.num = num;
    }

    public synchronized void increment() throws InterruptedException {
//        if (num != 0) this.wait();
        // 防止虚假唤醒，等着好好的突然被唤醒，但是此时num还是不为0，但是if就执行一次会继续往下执行，
        // 所以使用while可以再次判断条件，让线程继续等待
        while (num != 0) this.wait();
        ++num;
        System.out.println(Thread.currentThread().getName() + "=>" + num);
        this.notifyAll();
    }

    public  synchronized void decrement() throws InterruptedException {
//        if (num == 0) this.wait();
        // 防止虚假唤醒
        while (num == 0) this.wait();
        --num;
        System.out.println(Thread.currentThread().getName() + "=>" + num);
        this.notifyAll();
    }
}
